package com.hongdee.crm.task.service.impl;

import com.hongdee.annotation.MethodComment;
import com.hongdee.base.basedao.impl.BaseDaoImpl;
import com.hongdee.common.util.DateUtils;
import com.hongdee.crm.car.entity.TCrmCar;
import com.hongdee.crm.car.service.ITCrmCarService;
import com.hongdee.crm.carConfig.dao.ITCrmCarRefDao;
import com.hongdee.crm.task.dao.IBcMaintainTypeTaskDao;
import com.hongdee.crm.task.dao.ITCrmCarMaintainTaskDao;
import com.hongdee.crm.task.dao.ITCrmTaskDao;
import com.hongdee.crm.task.dao.ITCrmTaskUserCountDao;
import com.hongdee.crm.task.entity.TCrmTask;
import com.hongdee.crm.task.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 名  称:TCrmTimeTaskServiceImpl
 * 类  型: class
 * 描  述: 任务中心相关定时任务处理Service
 * 路  径:com.hongdee.crm.task.service.impl
 * 作  者:wangshuai
 * 日  期:2017/2/28 10:25
 */
@Service
public class TCrmTimeTaskServiceImpl extends BaseDaoImpl implements ITCrmTimeTaskService {

    private Logger logger = LoggerFactory.getLogger(TCrmTaskServiceImpl.class);

    private final int LIMIT = 1000;
    @Autowired
    private ITCrmTaskDao taskDao;
    @Autowired
    private ITCrmCarRefDao carRefDao;
    @Autowired
    private IBcMaintainTypeTaskDao maintainTypeTaskDao;
    @Autowired
    private ITCrmCarRefDao crmCarRefDao;
    @Autowired
    private ITCrmTaskUserCountDao userCountDao;

    @Autowired
    private ITCrmTaskService taskService;

    @Autowired
    private ITCrmCarWorkorderTaskService crmCarWorkorderTaskService;

    @Autowired
    private ITCrmCarService crmCarService;

    /*保养里程*/
    @Autowired
    private ITCrmCarMaintainMileTaskService crmCarMaintainMileTaskService;
    /*首保*/
    @Resource(name = "firstCarMaintainTaskService")
    private ITCrmCarMaintainTaskService crmCarMaintainTaskService;
    /*二保*/
    @Resource(name = "TwoCarMaintainTaskService")
    private ITCrmCarMaintainTaskService twoCrmCarMaintainTaskService;
    /*定保*/
    @Resource(name = "dbCarMaintainTaskService")
    private ITCrmCarMaintainTaskService dbCarMaintainTaskService;
    /*新车首月*/
    @Resource(name = "FirstMonthMaintainTaskService")
    private ITCrmCarMaintainTaskService firstMonthMaintainTaskService;

    /*车辆标签*/
    @Autowired
    private ITCrmCarPropertyTaskService crmCarPropertyTaskService;
    /*车辆回厂*/
    @Autowired
    private ITCrmCarBackToFacTaskService crmCarBackToFacTaskService;
    /*质保 延保*/
    @Autowired
    private ITCrmCarWarrantyTaskService crmCarWarrantyTaskService;
    /* 基盘 车辆行驶里程 */
    @Autowired
    private ICarBaseCountService carBaseCountService;

    @Autowired
    private ITCrmCarMaintainTaskDao crmCarMaintainTaskDao;


    /****
     * 关爱生日类service
     * 根据 t_crm_car表owner_birthday字段的月日减去提前天数与当前月判断，
     * 是否一致，一致则认为该月进行提醒，插入任务表
     * @throws Exception
     */
    @Override
    @MethodComment(name = "定时任务关爱 生日提醒")
    public Integer guanAiShengRiQuartz() throws Exception {
        String pcode = "ga";
        String code = "sr";
        logger.info("关爱生日任务开启" + System.currentTimeMillis());
        Integer nums = 0;
        List<Map<String, Object>> mapList = maintainTypeTaskDao.findCompanyList(pcode + "_" + code, code);
        if (mapList == null) {
            return nums;
        }
        for (Map<String, Object> map : mapList) {
            String companyId = String.valueOf(map.get("company_id"));
            int num = taskService.guanAiShengRi(companyId, "", "");
            nums += num;
        }
        return nums;
    }

    /****
     * 关爱-质保
     * 根据车辆表的质保开始时间加上三年减去提前提醒时间，进行判断是否与当月一致
     *
     * @throws Exception
     */
    @Override
    @MethodComment(name = "定时任务关爱 质保提醒")
    public Integer guanAiZhiBaoQuartz() throws Exception {
        Integer nums = 0;
        String pcode = "ga";
        String code = "zbt";
        List<Map<String, Object>> mapList = maintainTypeTaskDao.findCompanyList(pcode + "_" + code, code);
        if (mapList == null) {
            return nums;
        }
        for (Map<String, Object> map : mapList) {
            String companyId = String.valueOf(map.get("company_id"));
            int num = taskService.guanAiZhiBao(companyId, "", "");
            nums += num;
        }
        return nums;
    }

    /****
     * 关爱-延保
     * 从延保表中根据延保结束日期减去提前天数与当前年月进行判断
     * 一致则认为延保到期提醒
     * 将延保表信息与车辆表信息组合任务信息插入任务表
     * @throws Exception
     */
    @Override
    @MethodComment(name = "定时任务关爱 延保提醒 ")
    public Integer guanAiYanBaoQuartz() throws Exception {
        Integer nums = 0;
        String pcode = "ga";
        String code = "ybt";
        List<Map<String, Object>> mapList = maintainTypeTaskDao.findCompanyList(pcode + "_" + code, code);
        if (mapList == null) {
            return nums;
        }
        for (Map<String, Object> map : mapList) {
            String companyId = String.valueOf(map.get("company_id"));
            int num = taskService.guanAiYanBao(companyId, "", "");
            nums += num;
        }
        return nums;
    }

    /****
     * 流失类
     * 先从工单表中查询n月到n-1个月存在工单信息的车辆记录
     * 在排除掉工单表中查询现在到n-1个月存在工单的车辆记录
     * 关联车辆信息表查询车辆信息插入到任务表
     * @throws Exception
     */
    @Override
    @MethodComment(name = "定时任务流失提醒")
    public Integer liuShiQuartz() throws Exception {
        Integer nums = 0;
        List<Map<String, Object>> mapList = maintainTypeTaskDao.findCompanyByPCodeList("ls");
        if (mapList == null) {
            return nums;
        }
        for (Map<String, Object> map : mapList) {
            String companyId = String.valueOf(map.get("company_id"));
            int num = taskService.liuShi(companyId, "", "");
            nums += num;
        }
        return nums;
    }

    /****
     * * 处理保险类别-次年／续保／接待类任务
     * 根据类型（次年，续保，接待）／保险类别（交强险，商业险）查询保险表中生效日期+1年减去提前提醒日期判断是否与当年月一致
     * 一致则查询车辆信息插入任务表
     * 次年-交强险，次年-商业险，续保交强险，续保商业险，接待交强险，接待商业险处理方式类同
     *
     * 保险类-次年-交强险
     * @throws Exception
     */
    @Override
    @MethodComment(name = "定时任务保险 次年交强险提醒")
    public Integer ciNianJiaoQiangQuartz() throws Exception {
        //LSGBC5348GG047374的车主[曲秀杰]将于2016-12-09交强险到期,[15550880216].
        Integer nums = 0;
        String pcode = "bxcn";
        String code = "cnj";
        List<Map<String, Object>> lists = taskDao.beforDays(code, pcode + "_" + code);
        if (lists.size() == 0) {
            return nums;
        }
        for (Map<String, Object> map : lists) {
            if (map.get("v") == null) {
                continue;
            }
            String companyId = String.valueOf(map.get("company_id"));
            int num = taskService.ciNianJiaoQiang(companyId, "", "");
            nums += num;
        }
        return nums;
    }


    /****
     * 保险类-次年-商业险
     * @throws Exception
     */
    @Override
    @MethodComment(name = "定时任务保险 次年商业险提醒")
    public Integer ciNianShangYeQuartz() throws Exception {
        Integer nums = 0;
        String pcode = "bxcn";
        String code = "cns";
        List<Map<String, Object>> lists = taskDao.beforDays(code, pcode + "_" + code);
        if (lists.size() == 0) {
            return nums;
        }

        for (Map<String, Object> map : lists) {
            if (map.get("v") == null) {
                continue;
            }
            String companyId = String.valueOf(map.get("company_id"));
            int num = taskService.ciNianShangYe(companyId, "", "");
            nums += num;
        }
        return nums;
    }

    /****
     * 保险类-续保-商业
     * @throws Exception
     */
    @Override
    @MethodComment(name = "定时任务保险 续保商业险提醒")
    public Integer xuBaoShangYeQuartz() throws Exception {
        Integer nums = 0;
        String pcode = "bxxb";
        String code = "xbs";
        List<Map<String, Object>> lists = taskDao.beforDays(code, pcode + "_" + code);
        if (lists.size() == 0) {
            return nums;
        }

        for (Map<String, Object> map : lists) {
            if (map.get("v") == null) {
                continue;
            }
            String companyId = String.valueOf(map.get("company_id"));
            int num = taskService.xuBaoShangYe(companyId, "", "");
            nums += num;
        }
        return nums;
    }

    /****
     * 保险类-续保-交强险
     * @throws Exception
     */
    @Override
    @MethodComment(name = "定时任务保险 续保交强险提醒")
    public Integer xuBaoJiaoQiangQuartz() throws Exception {
        Integer nums = 0;
        String pcode = "bxxb";
        String code = "xbj";
        List<Map<String, Object>> lists = taskDao.beforDays(code, pcode + "_" + code);
        if (lists.size() == 0) {
            return nums;
        }

        for (Map<String, Object> map : lists) {
            if (map.get("v") == null) {
                continue;
            }
            String companyId = String.valueOf(map.get("company_id"));
            int num = taskService.xuBaoJiaoQiang(companyId, "", "");
            nums += num;
        }
        return nums;
    }

    /****
     * 保险类-保险接待-商业险
     * @throws Exception
     */
    @Override
    @MethodComment(name = "定时任务保险 保险接待 商业险提醒")
    public Integer jieDaiShangYeQuartz() throws Exception {
        Integer nums = 0;
        String pcode = "byjd";
        String code = "jds";
        List<Map<String, Object>> lists = taskDao.beforDays(code, pcode + "_" + code);
        if (lists.size() == 0) {
            return nums;
        }

        for (Map<String, Object> map : lists) {
            if (map.get("v") == null) {
                continue;
            }
            String companyId = String.valueOf(map.get("company_id"));
            int num = taskService.jieDaiShangYe(companyId, "", "");
            nums += num;
        }
        return nums;
    }

    /****
     * 保险类-保险接待-交强险
     * @throws Exception
     */
    @Override
    @MethodComment(name = "定时任务保险 保险接待 交强险提醒")
    public Integer jieDaiJiaoQiangQuartz() throws Exception {
        Integer nums = 0;
        String pcode = "byjd";
        String code = "jdj";
        List<Map<String, Object>> lists = taskDao.beforDays(code, pcode + "_" + code);
        if (lists.size() == 0) {
            return nums;
        }

        for (Map<String, Object> map : lists) {
            if (map.get("v") == null) {
                continue;
            }
            String companyId = String.valueOf(map.get("company_id"));
            int num = taskService.jieDaiJiaoQiang(companyId, "", "");
            nums += num;
        }
        return nums;
    }

    /****
     * 保险类-活跃
     *
     * 先从工单表中查询有效进场2次及以上车辆信息
     * 排除掉保险表有中当期保险信息的车辆信息
     * 联合车辆信息表查询车辆信息并插入到保险表中
     *
     * @throws Exception
     */
    @Override
    @MethodComment(name = "定时任务保险 活跃用户")
    public Integer baoXianHuoYueQuartz() throws Exception {
        Integer nums = 0;
        String pcode = "bxhy";
        String code = "hyt";
        List<Map<String, Object>> lists = taskDao.beforDays(code, pcode + "_" + code);
        if (lists.size() == 0) {
            return nums;
        }
        for (Map<String, Object> map : lists) {
            if (map.get("v") == null) {
                continue;
            }
            String companyId = String.valueOf(map.get("company_id"));
            int num = taskService.baoXianHuoYue(companyId, "", "");
            nums += num;
        }
        return nums;
    }

    /****
     * 保险类-非活跃
     *
     * 先查询工单表中2年内有效进厂次数大于等于1次的车辆信息
     * 在排除掉保险表中存在当期保险信息的车辆
     * 联合车辆信息表查询车辆信息插入到任务表中
     *
     * @throws Exception
     */
    @Override
    @MethodComment(name = "定时任务保险 非活跃用户")
    public Integer baoXianFeiHuoYueQuartz() throws Exception {
        Integer nums = 0;
        String pcode = "bxfhy";
        String code = "fhyt";
        List<Map<String, Object>> lists = taskDao.beforDays(code, pcode + "_" + code);
        if (lists.size() == 0) {
            return nums;
        }

        for (Map<String, Object> map : lists) {
            if (map.get("v") == null) {
                continue;
            }
            String companyId = String.valueOf(map.get("company_id"));
            int num = taskService.baoXianFeiHuoYue(companyId, "", "");
            nums += num;
        }
        return nums;
    }

    @Override
    @MethodComment(name = "延保类型根据类型中文写入类型ID")
    public Integer yanBaoLeiXingIdQuartz() throws Exception {
        // String sql = "UPDATE t_crm_car_exsurance ex SET ex.exsurance_company_id = CASE WHEN (LOCATE('厂',exsurance_company_name) OR exsurance_company_name like '上汽%') THEN '1' WHEN (LOCATE('润',exsurance_company_name) OR exsurance_company_name LIKE '自主%') THEN '2' END";
        //eturn this.getJdbcDao().update(sql);
        return 0;
    }

    /****
     * 关爱类-年审
     *
     * 查询所有车辆信息，先计算车辆年限，根据6年以内，6到15年，15年以上进行分类
     * 6年内判断是年限是否与2的倍数是则判断月日减去提前时间是否与当前月一致，一致则认为生成提醒任务
     * 6-15年则只判断月日减去提前时间是否与当前月一致，一致则任务生成任务
     * 15年以上，则根据月日生成当年两次年审日期，减去提前日期与当前月进行判断，是则生成提醒任务
     *
     * @throws Exception
     */
    @Override
    @MethodComment(name = "定时任务关爱 年审提醒")
    public Integer nianShenQuartz() throws Exception {
        Integer nums = 0;
        String pcode = "ga";
        String code = "ns";
        List<Map<String, Object>> lists = taskDao.beforDays(code, pcode + "_" + code);
        if (lists.size() == 0) {
            return nums;
        }
        for (Map<String, Object> map : lists) {
            String companyId = String.valueOf(map.get("company_id"));
            int num = taskService.nianShen(companyId, "", "");
            nums += num;
        }
        return nums;
    }

    @Override
    public void countSaIDNums() throws Exception {
        taskService.countSaIDNums();
    }

    /**
     * 更新与保养有关定时任务
     *
     * @throws Exception
     */
    @Override
    public void maintainTimeTaskDay() throws Exception {
        //更新车辆工单车辆ID
        //crmCarWorkorderTaskService.updWorkOrderCaridInfoQuartz();
        //更新车辆工单维修类别
        //crmCarWorkorderTaskService.bulidWorkorderPropertyQuartz();
        //更新车辆工单索赔维修类别
        // crmCarWorkorderTaskService.bulidWorkorderPropertyBySpQuartz();

        //更新车辆工单产值
        // crmCarWorkorderTaskService.updWorkOrderAmountInfoQuartz();
        //根据工单生成保养工单
        // crmCarMaintainMileTaskService.createCarMaintainMileQuartz();
        //更新车辆行驶里程
        // carBaseCountService.updateRunMileQuartz();
        //延保
        //crmCarWarrantyTaskService.updCarExsuranceInfoQuartz();
        //质保
        //crmCarWarrantyTaskService.updCarWarrantyInfoQuartz();
        //社会招揽
        // crmCarMaintainMileTaskService.carSolicitMaintainTaskQuartz();
        //流失返还生成保养工单
        // crmCarMaintainMileTaskService.carLossToBackMaintainTaskQuartz();
        //更新车辆行驶里程
        //carBaseCountService.updateRunMileQuartz();

        //刷新续保合同结束时间
        // this.updInsuranceEndDateQuartz();
        //根据销售数据
        this.updFromCompanyQuartz();
        //新车首月任务提醒
        // this.firstMonthMaintainTaskService.carMaintainQuartz();
        //更新延保平均保养里程
        this.updExsuranceMaintainAvgMile();
        //更新未处理任务信息
//        this.countSaIDNums();
    }

    /**
     * 每月任务 主要是首保、二保、定保
     *
     * @throws Exception
     */
    @Override
    public void maintainTimeTaskMonth() throws Exception {
//        crmCarMaintainTaskService.carMaintainQuartz();
//        twoCrmCarMaintainTaskService.carMaintainQuartz();
//        dbCarMaintainTaskService.carMaintainQuartz();
        /****
         * 任务自动确认
         * ***/

//        List<String> idList = autoCompanyIds();
//        for (String id : idList) {
//            logger.info("开始自动确认保养任务：" + id);
//            taskService.transferTask("", "", "", "", id);
//        }
    }

    /**
     * 保险、关爱、年审、流失定时任务
     *
     * @throws Exception
     */
    @Override
    public void bngTaskDay() throws Exception {
//        /*关爱*/
//        guanAiShengRiQuartz();
//        guanAiZhiBaoQuartz();
//        guanAiYanBaoQuartz();
//        /*流失*/
//        liuShiQuartz();
//        /*年审*/
//        nianShenQuartz();
//        /*保险*/
//        ciNianJiaoQiangQuartz();
//        ciNianShangYeQuartz();
//        xuBaoShangYeQuartz();
//        xuBaoJiaoQiangQuartz();
//        jieDaiShangYeQuartz();
//        jieDaiJiaoQiangQuartz();
//        baoXianHuoYueQuartz();
//        baoXianFeiHuoYueQuartz();
        /****
         * 任务自动确认
         * ***/
//        List<String> idList = autoCompanyIds();
//        for (String id : idList) {
//            logger.info("开始自动确认关爱、流失、保险任务：" + id);
//            taskService.transferTask("", "", "", "", id);
//        }
    }

    /**
     * 车辆标签定时任务
     */
    @Override
    public void carlabelTaskDay() throws Exception {
        /*执行车辆标签前 先半车辆标签清空*/
        crmCarPropertyTaskService.truncateCrmCarProperty();
        /*执行车辆标签任务*/
        crmCarPropertyTaskService.newCarLabelTaskQuartz();
        crmCarPropertyTaskService.carSolicitLabelTaskQuartz();
        crmCarPropertyTaskService.carLossToBackLabelTaskQuartz();
        crmCarPropertyTaskService.carLossLabelTaskQuartz();
        crmCarPropertyTaskService.carAccidentLabelTaskQuartz();
        crmCarPropertyTaskService.threeFactoryActivityTaskQuartz();
    }

    /**
     * 车辆回厂定时任务
     *
     * @throws Exception
     */
    @Override
    public void carBackFacTaskDay() throws Exception {
        //保养回厂定时任务
        crmCarBackToFacTaskService.carMaintainBackToFacQuartz();
        //保养回厂关闭任务
        crmCarBackToFacTaskService.closeMaintainBackToFacTaskQuartz();
        //流失回厂
        crmCarBackToFacTaskService.carLsTaskBackToFacQuartz();
        //流失回厂关闭任务
        crmCarBackToFacTaskService.closelsTaskBackToFacTaskQuartz();
    }


    /**
     * 根据车辆销售数据 更新车辆from_company字段为是
     *
     * @throws Exception
     */
    @Override
    @MethodComment(name = "车辆销售数据 更新车辆from_company字段为是")
    public Integer updFromCompanyQuartz() throws Exception {
        String sql = "update  t_crm_car car , t_crm_car_sale sale set car.from_company='是',car.buy_date=sale.buy_date,car.owner_name=sale.owner_name," +
                " car.owner_phone=sale.owner_phone,car.owner_tel = sale.owner_phone  " +
                " where sale.company_id=car.company_id and sale.vin=car.vin ";
//        String sql = "update t_crm_car set from_company='是' where id in ( " +
//                "select id from (select car.id from t_crm_car_sale sale, " +
//                "t_crm_car car " +
//                "where sale.company_id=car.company_id and sale.vin=car.vin) t )";
        return this.taskDao.executeSQL(sql);
    }

    /*****
     *  1.将新增的销售数据生成简版的车辆档案
     *  生成规则：
     *      VIN+公司 ID 在销售明细表中存在 不在车辆档案表中存在的记录，插入到车辆档案
     *@修改人 zhguokai
     *@修改时间： 2017-09-01
     *@修改内容： 将重复性判断由 id 改为 VIN
     */
    @Override
    @MethodComment(name = "将销售数据中，未生成车主档案的销售信息，生成车主档案")
    public Integer createCrmCarInfoBySaleQuartz(String companyId) throws Exception {
        StringBuffer sql = new StringBuffer();
        sql.append("INSERT INTO t_crm_car (id,plate_num,vin,buy_date,from_company,saler,owner_name,owner_tel,owner_phone,contact_name,contact_tel,contact_phone,manitain_sender,sender_tel,sender_phone,owner_city,owner_address,company_id,series,model)  " +
                "SELECT s.id,s.plate_num,s.vin,s.buy_date,'是',s.saler,s.owner_name,s.owner_phone,s.owner_phone,s.owner_name,s.owner_phone,s.owner_phone,s.owner_name,s.owner_phone,s.owner_phone,concat(s.city,s.area),s.address,s.company_id,s.series,s.model FROM t_crm_car_sale s WHERE NOT EXISTS ( " +
                "SELECT 1 FROM t_crm_car c WHERE s.vin=c.vin AND c.company_id=s.company_id) and vin is not NULL AND company_id = ?");
        return this.carRefDao.executeSQL(sql.toString(), companyId);
    }


    /**
     * 更新定时任务中的处理人信息
     * 1、获得未指定处理人的任务
     * 2、循环遍历任务信息
     * 3、获得公司下的车牌规则
     * 4、根据规则、车牍号 获得指定人
     * @throws Exception
     */
    //--------------------2017-04-08 暂时废弃
//    @Override
//    @MethodComment(name = "根据车辆分配规则，更新任务SAID")
//    public Integer updCrmTaskSaIdQuartz() throws Exception {
//        Integer nums=0;
//        //1、获得公司信息
//        List<Map<String,Object>> companyList=carRefDao.findCompanyList();
//        if(companyList.size()>0){
//            //2、遍历公司信息，循环获得任务信息（任务表与任务类型设置表关联）
//            for (Map<String, Object> comMap:companyList){
//                int start=0;
//                //公司ID
//                String companyId=String.valueOf(comMap.get("company_id"));
//                while(true){
//                    List<Map<String,Object>> taskList=taskDao.findTaskByComapnyId(companyId,start*LIMIT,LIMIT);
//                    if(taskList.size()<=0){
//                        start=0;
//                        break;
//                    }
//                    //处理任务信息
//                    //3、遍历任务信息，根据任务中的车牌号，获得车辆设置信息
//
//                    List<TCrmTask> lists=this.analyTaskList(taskList,companyId);
//                    //4、设置任务信息
//                    if(lists.size()>0){
//                        nums+=lists.size();
//                        taskDao.updBatchCrmTaskSaId(lists);
//                    }
//                    //5、批量更新
//                    start++;
//                }
//            }
//        }
//        return nums;
//    }
//
//
//
//    /**
//     * 解析任务信息
//     * @param taskList 任务列表
//     * @param companyId 公司ID
//     * @throws Exception
//     */
//    private List<TCrmTask> analyTaskList(List<Map<String,Object>> taskList,String companyId)throws Exception{
//        List<TCrmTask> lists=new ArrayList<>();
//        for(Map<String,Object> taskMap:taskList){
//            //取出角色信息、车牌信息、车牌尾号、尾数信息
//            String roleId=String.valueOf(taskMap.get("role_id"));
//            //获得对应的
//            List<Map<String,Object>> carRefList=taskDao.findRoleTypeByRoleId(roleId,companyId);
//            String plateNum=String.valueOf(taskMap.get("plateNum"));
//            if(plateNum==null || "".equals(plateNum)){
//                continue;
//            }
//            //取出尾号
//            String lastStr=plateNum.substring(plateNum.length()-1,plateNum.length());
//            //取出尾数
//            String plateNum_n=this.getNumbersByStr(plateNum);
//            String lastNum=plateNum_n.substring(plateNum_n.length()-1,plateNum_n.length());
//            String uid=this.checkPlateNum(carRefList,lastStr,lastNum);
//            if(uid==null || "null".equals(uid)){
//                continue;
//            }else{
//                TCrmTask crmTask=new TCrmTask();
//                crmTask.setId(String.valueOf(taskMap.get("id")));
//                crmTask.setSaId(uid);
//                lists.add(crmTask);
//            }
//        }
//        return lists;
//    }
//
//    /**
//     * 检测车牌号
//     * @param carRefList
//     * @param lastStr
//     * @param lastNum
//     * @return
//     */
//    private String checkPlateNum(List<Map<String,Object>> carRefList,String lastStr,String lastNum){
//        for (Map<String,Object> carRefMap:carRefList) {
//            String type=String.valueOf(carRefMap.get("type"));
//            String value=String.valueOf(carRefMap.get("value"));
//            String uid=String.valueOf(carRefMap.get("u_id"));
//            if(type.equals("2")){
//                if(value.indexOf(lastNum)>-1){
//                    return uid;
//                }
//            }else if(type.equals("1")){
//                if(value.indexOf(lastStr)>-1){
//                    return uid;
//                }
//
//            }else if(type.trim().equals("")){
//                return uid;
//            }
//        }
//        return null;
//    }
//
//    private void findTaskSaNameByPlateNum(List<Map<String,Object>> mapList){
//        for(Map<String,Object> map:mapList){
//            //取出车牌号
//            String plateNum=String.valueOf(map.get("plate_num"));
//            //取出必号
//            String lastStr=plateNum.substring(plateNum.length()-1,plateNum.length());
//            //取出尾数
//            String plateNum_n=this.getNumbersByStr(plateNum);
//            String lastNum=plateNum_n.substring(plateNum_n.length()-1,plateNum_n.length());
//            //公司ID
//            String companyId=String.valueOf(map.get("company_id"));
//
//        }
//    }
//
//    private String getNumbersByStr(String plateNum){
//        String regEx="[^0-9]";
//        Pattern p = Pattern.compile(regEx);
//        Matcher m = p.matcher(plateNum);
//        return m.replaceAll("").toString();
//    }


    //按车辆分配规则查询


    /**
     * 1、根据任务处理权限，找到相应的处理人
     * 2、根据处理权限+处理人对应的车辆=更新任务SAID
     *
     * @return
     * @throws Exception
     */
    @Override
    @MethodComment(name = "根据车辆分配规则，更新任务SAID")
    public Integer updCrmTaskSaIdQuartz() throws Exception {
        Integer nums = new Integer(0);
        List<Map<String, Object>> companyList = carRefDao.findCompanyByTaskTypeList();
        if (companyList.size() > 0) {
            //遍历公司信息
            for (Map<String, Object> companyMap : companyList) {
                String companyId = String.valueOf(companyMap.get("company_id"));
                nums += this.updCrmTaskSaId(companyId);
            }
        }
        return nums;
    }

    @Override
    public Integer updCrmTaskSaId(String companyId) throws Exception {
        int nums = 0;
        //获得公司所有的部门ID
        List<String> deptList = new ArrayList<>();
        deptList.add(companyId);
        this.buildDeptChild(companyId, deptList);
        //获得公司下所有的处理任务的信息
        List<Map<String, Object>> roleList = carRefDao.findRoleByCompanyIdList(companyId);
        //遍历角色信息
        for (Map<String, Object> roleMap : roleList) {
            String roleId = String.valueOf(roleMap.get("role_id"));
            String taskCode = String.valueOf(roleMap.get("task_code"));
            //根据公司ID，角色ID，获得角色对应的人员信息
            List<Map<String, Object>> userList = crmCarRefDao.findRoleUserByCompanyIdAndRoleId(roleId, deptList);
            //遍历人员 逐个更新修改
            for (Map<String, Object> userMap : userList) {
                String uid = String.valueOf(userMap.get("uid"));
                int num = this.updTaskSaId(uid, taskCode, companyId);
                nums += num;
            }
        }
        return nums;
    }

    /**
     * 更新任务SAID
     *
     * @param uid
     * @param taskCode
     * @param companyId
     * @return
     * @throws Exception
     */
    private Integer updTaskSaId(String uid, String taskCode, String companyId) throws Exception {
        List<String> paramList = new ArrayList<>();
        StringBuffer sqlStr = new StringBuffer();
        sqlStr.append("UPDATE t_crm_task_real taskReal,t_crm_car_ref_detail detail " +
                "set taskReal.sa_id=detail.uid " +
                "where taskReal.vin=detail.vin and detail.uid=? and taskReal.sa_id is NULL ");
        paramList.add(uid);
        String[] taskCodes = taskCode.split(",");
        sqlStr.append("and taskReal.type_code in(");
        for (int i = 0; i < taskCodes.length; i++) {
            paramList.add(taskCodes[i]);
            sqlStr.append("?");
            if (i < (taskCodes.length - 1)) {
                sqlStr.append(",");
            }
        }
        sqlStr.append(") ");
        sqlStr.append("and taskReal.company_id=? ");
        paramList.add(companyId);
        return this.carRefDao.executeSQL(sqlStr.toString(), paramList.toArray());
    }


    //伪递归查询公司下所有部门
    private List<Map<String, Object>> buildDeptChild(String opId, List<String> deptList) throws Exception {
        String sqlStr = "select * from t_bc_organ  where o_p_id = ? ";
        List<Map<String, Object>> child = this.crmCarRefDao.list(sqlStr, opId);
        return buildDeptParent(child, deptList);
    }

    private List<Map<String, Object>> buildDeptParent(List<Map<String, Object>> paranet, List<String> deptList) throws Exception {
        if (paranet.size() == 0) {
            return paranet;
        }
        String pId;
        for (Map<String, Object> temp : paranet) {
            pId = String.valueOf(temp.get("id"));
            List<Map<String, Object>> childList = buildDeptChild(pId, deptList);
            temp.put("child", childList);
            deptList.add(pId);
        }
        return paranet;
    }

//    /**
//     * 1、查询出全部的车辆分配规则 按规则按升序 0 1 2
//     * 2、遍历人员 查询角色
//     * 3、查询sql 根据查询sql更新任务saID
//     *
//     * @return
//     * @throws Exception
//     */
//    @Override
//    @MethodComment(name = "根据车辆分配规则，更新任务SAID")
//    public Integer updCrmTaskSaIdQuartz() throws Exception {
//        Integer nums = 0;
//        List<Map<String, Object>> companyList = carRefDao.findCompanyList();
//        if (companyList.size() > 0) {
//            for (Map<String, Object> companyMap : companyList) {
//                String companyId = String.valueOf(companyMap.get("company_id"));
//                //该分配下所有分配了车辆规则的用户信息
//                List<Map<String, Object>> userMapList = carRefDao.findUserByCompnayIdList(companyId);
//                //遍历用户信息 获得其分配的处理角色信息
//                for (Map<String, Object> userMap : userMapList) {
//                    String uid = String.valueOf(userMap.get("u_id"));
//                    List<Map<String, Object>> roles = this.taskDao.findRoleByUid(uid);
//                    if (roles == null || roles.size() == 0) {
//                        continue;
//                    }
//                    int numby = this.updByAndLsSaId(companyId, uid, roles, userMap, "");
////                    int numls = this.updByAndLsSaId(companyId, uid, roles, userMap, "ls");
//                    nums +=numby;
//                }
//
//            }
//        }
//        return nums;
//    }

//    private Integer updByAndLsSaId(String companyId, String uid, List roles, Map userMap, String type) throws Exception {
//        StringBuffer sqlstr = new StringBuffer();
//        String sql = this.carRefSql(companyId, uid, roles, userMap, Constant.TASKPOWER.HANDLE.ordinal());
//        if (sql != null) {
//            List<String> list=new ArrayList<>();
//            //2017-04-11 只更新保养 流失类said
//            sqlstr.append("update t_crm_task_real  crmtask set crmtask.sa_id=?,assign_id='-1',assign_name='系统' where company_id=? AND crmtask.sa_id is null ");
//            list.add(uid);
//            list.add(companyId);
//            if(!"".equals(type)){
//                sqlstr.append("and crmtask.type_pcode=? ");
//                list.add(type);
//            }
//            sqlstr.append(sql);
//
//            int num = this.taskDao.executeSQL(sqlstr.toString(),list.toArray());
//            return num;
//        }
//        return 0;
//    }
//
//
//    /**
//     * 生成查询sql
//     *
//     * @param companyId
//     * @param uid
//     * @param roles
//     * @param datas
//     * @param type
//     * @return
//     * @throws Exception
//     */
//    private String carRefSql(String companyId, String uid, List<Map<String, Object>> roles, Map<String, Object> datas, int type) throws Exception {
//        StringBuffer sqlStr = new StringBuffer();
//        List<String> ps = new ArrayList<>();
//        /*****
//         * 该用户所有的角色之和 查询所分配的任务类型之和，此处需要修改
//         * ****/
//        Map taskTypeMap = new HashMap();
//        for (Map<String, Object> role : roles) {
//            taskTypeMap.putAll(this.taskDao.findCodeByRId(companyId, role.get("r_id").toString(), String.valueOf(type)));
//        }
//        if (taskTypeMap.size() == 0) {
//            return null;
//        }
//        //角色特殊条件过滤
//        if (taskTypeMap.size() > 0) {
//            sqlStr.append(" and crmtask.type_code in (");
//            for (Object key : taskTypeMap.keySet()) {
//
//                sqlStr.append(" '" + String.valueOf(key) + "', ");
//            }
//            sqlStr.append(" '' ) ");
//        }
//        Map<String, Object> has = new HashMap<String, Object>();
//        String tmp = null;
//        String tmps[] = null;
//        //可能存在单个value字段1，2，3样式，需先分割开
//        if (datas.get("value") != null) {
//            tmp = datas.get("value").toString();
//            tmps = tmp.split(",");
//            for (int j = 0; j < tmps.length; j++) {
//                has.put(tmps[j], "1");
//            }
//            Object obj[] = has.keySet().toArray();
//            StringBuffer sb = new StringBuffer();
//            for (int i = 0; i < obj.length; i++) {
//                sb.append(obj[i].toString());
//                //sb.append(",");
//            }
//            //生成过滤语句
//            if (datas.get("type").toString().equals("1")) {
//                sqlStr.append(" AND  crmtask.plateNum REGEXP '[" + sb.toString().replaceAll(",", "") + "]$'  ");
//                ps.add(uid);
//            } else if (datas.get("type").toString().equals("2")) {
//                sqlStr.append(" AND crmtask.plateNum REGEXP '.*[" + sb.toString().replaceAll(",", "") + "][A-Za-z]*$' ");
//                ps.add(uid);
//            } else {//全部
//                //分配全部车辆
//            }
//        }
//        return sqlStr.toString();
//    }

    /**
     * 更新续保结束时间
     *
     * @return
     * @throws Exception
     */
    @Override
    @MethodComment(name = "更新续保结束时间")
    public Integer updInsuranceEndDateQuartz() throws Exception {
        Integer nums = 0;
        String sql = "update t_crm_car_insurance ie set ie.compulsory_end_date = FLOOR(UNIX_TIMESTAMP(DATE_SUB(DATE_ADD(  FROM_UNIXTIME(ie.compulsory_start_date/1000,'%Y-%m-%d'),INTERVAL 1 YEAR),INTERVAL 1 DAY))*1000) where ie.compulsory_end_date is null";
        nums += taskDao.executeSQL(sql);
        String sql2 = "update t_crm_car_insurance ie set ie.contractstopinsurance = FLOOR(UNIX_TIMESTAMP(DATE_SUB(DATE_ADD(  FROM_UNIXTIME(ie.contractstartinsurance/1000,'%Y-%m-%d'),INTERVAL 1 YEAR),INTERVAL 1 DAY))*1000) where ie.contractstopinsurance is null";
        nums += taskDao.executeSQL(sql2);
        return nums;
    }

    /**
     * 关闭指定公司指定任务信息
     *
     * @param companyId
     * @return
     * @throws Exception
     */
    @Override
    public Integer closeTaskByCompanyQuartz(String companyId) throws Exception {
//        String sql="update  t_crm_task_real taskreal, " +
//                "(select * from t_crm_car_workorder where wx_type in ('首保','二保','定保') and company_id=?) worder " +
//                "set taskreal.`status`=2 " +
//                "where taskreal.car_id=worder.car_id and taskreal.`status`<1 and taskreal.type_pcode='by' and taskreal.company_id=?";
//        return this.taskDao.executeSQL(sql,companyId,companyId);
        return 0;
    }

    /**
     * 券卡到期提醒
     *
     * @return
     * @throws Exception
     */
    @Override
    @MethodComment(name = "券卡到期提醒")
    public Integer couponExpireRemindQuqrtz() throws Exception {
        String pcode = "ga";
        String code = "qk";
        //获取公司信息
        Integer nums = 0;
        //鲁ALU398 的车主[李凯（润通）]参加活动[续保尊享-赠送更换机油机滤代金礼券一次（英朗）]的优惠券将于2017-05-24到期
        List<Map<String, Object>> mapList = maintainTypeTaskDao.findCompanyList(pcode + "_" + code, code);
        for (Map<String, Object> map : mapList) {
            String companyId = String.valueOf(map.get("company_id"));
            nums += this.couponExpireRemindByCompnayQuartz(companyId, "", "");
        }
        return nums;
    }

    @Override
    @MethodComment(name = "券卡到期提醒任务，根据公司生成")
    public Integer couponExpireRemindByCompnayQuartz(String companyId, String startTime, String endTime) throws Exception {
        String pcode = "ga";
        String code = "qk";
        String tpl = "%s 的车主[%s]参加活动[%s]的优惠券将于%s到期";
        int start = 0;
        int nums = 0;
        List<TCrmTask> taskList = new ArrayList<>();
        Integer beferDay = taskDao.beforDays(companyId, code, pcode + "_" + code);
        String nowTimeStr = DateUtils.getTimeStr("yyyy-MM-dd'T'00:00:00.000'Z'");
        long nowTime = DateUtils.parseTimeZoneStr(nowTimeStr);

        if (beferDay != null) {
            Long beferDayL = DateUtils.addDayLongTime(nowTime, -beferDay);
            String beferDayStr = DateUtils.formatLongTime(beferDayL, "yyyy-MM-dd");
            while (true) {
                StringBuffer sqlStr = new StringBuffer();
                List<Object> params = new ArrayList<>();
                sqlStr.append(" SELECT coupon.id, coupon.chanzhi, coupon.company_id, coupon.contact_name, coupon.contact_phone, coupon.dayin_date, coupon.gongdan_id, " +
                        " activity.`name`, car.plate_num, DATE_FORMAT(DATE_SUB(FROM_UNIXTIME(youxiaoqi/1000),INTERVAL ? DAY),'%Y-%m-%d') expireDate, ");
                params.add(beferDay);
                sqlStr.append(" DATE_FORMAT(FROM_UNIXTIME(youxiaoqi/1000),'%Y-%m-%d') endDate,car.vin,car.id carId" +
                        " FROM " +
                        " t_crm_car_coupon coupon, " +
                        " t_crm_car_activity activity, " +
                        " t_crm_car car " +
                        " WHERE " +
                        " coupon.activity_id = activity.id " +
                        " AND coupon.vin = car.vin " +
                        " AND coupon.company_id=? ");
                params.add(companyId);
                sqlStr.append(" AND coupon.youxiaoqi is not NULL " +
                        " AND coupon.use_date is NULL " +
                        " AND DATE_FORMAT(DATE_SUB(FROM_UNIXTIME(coupon.youxiaoqi/1000),INTERVAL ? DAY),'%Y%m')=DATE_FORMAT(NOW(),'%Y%m')");
                params.add(beferDay);
                sqlStr.append("and  " +
                        " DATE_FORMAT( " +
                        "  DATE_SUB( " +
                        "   FROM_UNIXTIME(youxiaoqi / 1000), " +
                        "   INTERVAL 30 DAY " +
                        "  ), " +
                        "  '%Y-%m-%d' " +
                        " )>=?");
                params.add(beferDayStr);
                sqlStr.append(" limit ?,?");

                params.add(start * LIMIT);
                params.add(LIMIT);
                List<Map<String, Object>> list = this.carRefDao.list(sqlStr.toString(), params.toArray());
                if (list.size() == 0) {
                    start = 0;
                    break;
                }
                for (Map<String, Object> map : list) {
                    String expireDate = String.valueOf(map.get("expireDate"));
                    boolean flag = true;
                    if (!"".equals(startTime) && !"".equals(endTime)) {
                        flag = DateUtils.checkTime(expireDate, startTime, endTime);
                    }
                    if (flag) {
                        TCrmTask tCrmTask = this.createCrmTask(companyId, map, expireDate, tpl, pcode, code);
                        if (tCrmTask != null) {
                            taskList.add(tCrmTask);
                        }
                    }
                }
                if (taskList.size() > 0) {
                    nums += taskList.size();
                    crmCarMaintainTaskDao.insertMaintailLists(taskList);
                }
                start++;
            }
        }
        return nums;
    }

    private TCrmTask createCrmTask(String companyId, Map<String, Object> car, String expectDate, String content, String pcode, String code) throws Exception {
        TCrmTask task = new TCrmTask();
        task.setCreateTime(new Date().getTime());
        task.setCompanyId(companyId);
        task.setVIN(car.get("vin").toString());
        task.setCarId(car.get("id").toString());
        task.setPlateNum(car.get("plateNum").toString());
        task.setLinkman(car.get("contactName").toString());
        if (car.get("contactPhone") != null) {
            task.setLinkphone(car.get("contactPhone").toString());
        }
        task.setContactId(car.get("id").toString());
        task.setExpectDate(expectDate);
        task.setStatus("0");
        task.setIsBack("0");
        task.setTypePCode(pcode);
        task.setTypeCode(code);
        content = String.format(content, task.getPlateNum(), task.getLinkman(), String.valueOf(car.get("name")), String.valueOf(car.get("endDate")));
        task.setContent(content);
        //验证任务是否重复
        boolean flag = taskDao.checkcouponTask(companyId, task.getCarId(), code, pcode, task.getExpectDate(), task.getContent());
        if (!flag) {
            return task;
        } else {
            return null;
        }
    }

    @Override
    @MethodComment(name = "更新延保平均保养里程")
    public Integer updExsuranceMaintainAvgMile() throws Exception {
        String sql = "update  t_crm_car_exsurance exs, " +
                "(select COUNT(id) nums,MAX(run_mile),vin,truncate(MAX(run_mile)/(COUNT(id)),2) avgMile from t_crm_car_workorder where  wx_type in ('首保','二保','定保') group by vin) t " +
                "set exs.avg_mile=t.avgMile " +
                "where exs.vin=t.vin ";
        return this.executeSQL(sql);
    }

    /******
     *
     * 从t_bc_param_set表中读取AutoTask为1的公司，逐步确认定时任务
     * code:autoTask 自动确认任务
     * value: 0 不自动确认，1 自动确认
     * @return
     * @throws Exception
     */
    private List<String> autoCompanyIds() throws Exception {
        logger.info("获取自动确认任务的单位");
        //查询自
        String sql = "select company_id from t_bc_param_set where code='autoTask' and value='1'";
        List<Map<String, Object>> companyList = this.carRefDao.list(sql);
        List<String> idList = new ArrayList<>();
        for (Map temp : companyList) {
            idList.add(String.valueOf(temp.get("companyId")));
        }
        return idList;
    }

}
